#include "dinogame.h"
#include "ui_dinogame.h"
#include<QKeyEvent>
#include <QRandomGenerator>
#include <QDebug>

dinogame::dinogame(QWidget *parent)
    : QWidget(parent),
    ui(new Ui::dinogame),dinoY(250), isjumping(false),
    jumpvelocity(0),obstacleSpawnTimer(0),gameover(true), score(0)
{
    ui->setupUi(this);
    loadimages();
    for(int i = 0; i < 20; i++) {
        obstacles.append(obstacle{0, 0, 0, 0, 0, 0, false});
    }
    setFixedSize(800, 400);
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &dinogame::updateGame);
}
void dinogame::startGame(){
    resetGame();
    timer->start(20);
}
void dinogame::loadimages(){
    background.load(":/images/images/background3.png");
    dinostand.append(QPixmap(":/images/images/dinostand1.png"));
    dinostand.append(QPixmap(":/images/images/dinostand2.png"));
    dinostand.append(QPixmap(":/images/images/dinostand3.png"));
    dinostand.append(QPixmap(":/images/images/dinostand4.png"));
    dinodown.append(QPixmap(":/images/images/dinodown1.png"));
    dinodown.append(QPixmap(":/images/images/dinodown2.png"));
    dinodown.append(QPixmap(":/images/images/dinodown3.png"));
    dinodown.append(QPixmap(":/images/images/dinodown4.png"));
    bird.append(QPixmap(":/images/images/bird1.png"));
    bird.append(QPixmap(":/images/images/bird2.png"));
    cactus.load(":/images/images/cactus.png");
}
void dinogame::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.drawPixmap(0,30,background);//绘制背景
    painter.drawText(650,30,QString("Score:%1").arg(score));
    if (isDucking) {
        if(currentframe2 < dinodown.size()){
            painter.drawPixmap(100, dinoY,dinodown[currentframe2]); // 下蹲
        }
    } else {
        if(currentframe1<dinostand.size()){
            painter.drawPixmap(100, dinoY,dinostand[currentframe1]); // 正常站立
        }
    }
    for(const auto &obs : obstacles) {
        if(obs.active) {
            switch(obs.type) {
            case 0: // 仙人掌
                painter.drawPixmap(obs.x,obs.y,cactus);
                //painter.setBrush(Qt::green);
                //painter.drawRect(obs.x, obs.y, obs.width, obs.height);
                break;
            case 1: // 鸟
                painter.drawPixmap(obs.x, obs.y,bird[currentframe3]);
                //painter.setBrush(Qt::blue);
                //painter.drawEllipse(obs.x, obs.y, obs.width, obs.height);
                break;
            }
        }
    }//绘制
    if (gameover) {
        QFont originalfont=painter.font();
        QFont bigfont=originalfont;
        bigfont.setPointSize(36);
        bigfont.setBold(true);
        painter.setFont(bigfont);
        QFont midfont=originalfont;
        midfont.setPointSize(24);
        midfont.setBold(true);
        painter.setFont(midfont);
        painter.drawText(QRect(0,120,width(),150), Qt::AlignCenter, "Press the space bar to Continue");
        painter.setFont(originalfont);
    }
}//游戏结束
bool dinogame::checkCollision(const obstacle &obs)
    {
        QRect dinoRect;
        if(isDucking) {
            dinoRect = QRect(100, dinoY, dinodown[currentframe2].width(), dinodown[currentframe2].height());
        }
        else if(isjumping){
                dinoRect = QRect(105, dinoY+5,dinostand[currentframe1].width()-25, dinostand[currentframe1].height()-25);
        }else{
            dinoRect = QRect(105, dinoY,dinostand[currentframe1].width()-15, dinostand[currentframe1].height());
        }
        QRect obsRect(obs.x+5, obs.y, obs.width, obs.height);//考虑到恐龙形态的特殊性，通过对两矩形x的更换放宽矩形检测要求，可以减少矩形判断的误差
        return dinoRect.intersects(obsRect);
    }//碰撞判定
void dinogame::spawnObstacle() {
    // 找一个未激活的障碍物
    for(auto &obs : obstacles) {
        if(!obs.active) {
            // 随机选择类型
            obs.type = QRandomGenerator::global()->bounded(2);
            // 根据类型设置属性
            switch(obs.type) {
            case 0: // 小仙人掌
                obs.width = 30;
                obs.height = 50;
                obs.y = 250;
                obs.speed = 8+score/40;
                break;
            case 1: // 鸟(飞行障碍)
                depleteheight=30;
                randval=QRandomGenerator::global()->bounded(100);
                obs.width = 40;
                obs.height = 30;
                if(randval<33){
                    obs.y = 210 + depleteheight;
                }else if(randval>=33&&randval<66){
                    obs.y = 210;
                }else{
                    obs.y =270;
                }
                obs.speed = 8+score/80;
                break;
            }

            obs.x = width();
            obs.active = true;
            return;
        }
    }
    // 如果没有空闲障碍物，动态添加一个新槽位
    obstacles.append(obstacle{0, 0, 0, 0, 0, 0, false});
    auto &newObs = obstacles.last();
    // ...初始化新障碍物...
    newObs.active = true;
}//障碍物的生成

void dinogame::keyPressEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Down && !downKeyPressed&&!gameover) {
        downKeyPressed = true;
        if (!isjumping) { // 在地面能立即下蹲
            isDucking = true;
            dinoY = DINO_DUCK_Y;
        }else if(isjumping){
            jumpvelocity+=20;
        }
        update(); // 请求重绘
    }
    if (event->key() == Qt::Key_Space && !isjumping) {
        if(gameover){
            resetGame();
        }
        else if(!isjumping&&!isDucking){
            isjumping = true;
            jumpvelocity=-15;
        }else if(isDucking){
            isjumping=false;
        }
    }
}
void dinogame::keyReleaseEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Down ) {
        downKeyPressed = false;
        isDucking = false;
        if (!isjumping) { // 只有在地面才恢复站立高度
            dinoY = DINO_STAND_Y;
        }
        update(); // 请求重绘
    }
}//键盘指令
void dinogame::resetGame()
{
    // 重置游戏状态
    dinoY = 250;
    isjumping = false;
    isDucking = false;
    jumpvelocity = 0;
    gameover = false;
    score = 0;
    currentframe1 = 0;
    currentframe2 = 0;
    framecounter1 = 0;
    framecounter2 = 0;
    currentframe3 = 0;
    currentframe3 = 0;
    while(obstacles.size() > 20) {
        obstacles.removeLast();
    }//游戏结束移除额外障碍物
    // 清除所有障碍物
    for(auto &obs : obstacles){
        if(checkCollision(obs)){
            obs.x=width();
        }else{
            obs.active=false;
        }
    }

    // 重新开始游戏循环
    timer->start(20);
}//重启游戏
void dinogame::updateGame() {
    //启动游戏
    static int startpoint=1;
    if(startpoint){
        startpoint++;
        if(startpoint>21){
            spawnObstacle();
            startpoint=0;
        }
    }
    // 游戏逻辑更新
    if(gameover){
        return;
    }
    if(!isDucking) {
        if(++framecounter1 >= frame_delay) {
            framecounter1 = 0;
            currentframe1 = (currentframe1 + 1) % dinostand.size();
        }
    }else{
        if(++framecounter2 >= frame_delay) {
            framecounter2=0;
            currentframe2 = (currentframe2 + 1) % dinodown.size();
        }
    }
    if(++framecounter3 >= frame_delay) {
        framecounter3=0;
        currentframe3 = (currentframe3 + 1) % bird.size();
    }
    // 1. 处理跳跃物理
    if (isjumping) {
        dinoY += jumpvelocity;
        jumpvelocity += 1;

        // 落地检测
        if (dinoY >= (downKeyPressed ? DINO_DUCK_Y : DINO_STAND_Y)) {
            dinoY = downKeyPressed ? DINO_DUCK_Y : DINO_STAND_Y;
            isjumping = false;

            // 落地时如果下键仍按住，保持下蹲
            isDucking = downKeyPressed;
        }
    }
    // 地面状态下键按住时强制下蹲
    else if (downKeyPressed && !isDucking) {
        isDucking = true;
        dinoY = DINO_DUCK_Y;
    }
    // 地面状态下键松开时强制站立
    else if (!downKeyPressed && isDucking) {
        isDucking = false;
        dinoY = DINO_STAND_Y;
    }
    bool newobstacle = false;
    // 更新所有障碍物位置
    for(auto &obs : obstacles) {
        if(obs.active) {
            obs.x -= obs.speed;
            // 检查是否移出屏幕左侧
            if(obs.x<250&&obs.x+obs.speed>=250) {
                spawnObstacle(); // 立即生成新障碍物
            }
            if(obs.x <-obs.width){
                obs.active=false;
            }
    // 3. 碰撞检测
    if (checkCollision(obs)) {
        gameover = true;        // 简单矩形碰撞检测
        isjumping=false;
    }
        }
    }
    if(newobstacle) {
        spawnObstacle();
    }
    static int count=0;
    count++;
    if(count%5==0){
        score++;//得分机制
    }
    update();  // 4. 触发界面重绘
    }//游戏逻辑更新
dinogame::~dinogame(){
    delete timer;
    delete ui;
}
